# coding: utf-8
#服务端
import pickle
import socket  # 导入模块
import struct  # 导入模块
import threading
import time

import keyboard

clients = {}
def start_server_async():
    time.sleep(2)
    din = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 基于网络家族以流的方式创建一个链接路
    #服务端关闭nagle算法
    din.setsockopt(socket.SOL_SOCKET, socket.TCP_NODELAY, True)
    ip = ('0.0.0.0', 8082)  # 设定服务端唯一的地址
    din.bind(ip)  # 绑定地址
    din.listen(10)  # 激活启动，设置链接池最大缓数量

    # protocol
    # 4个字节 cbaby
    # 1个字节 1：客户端注册 2：服务端推送
    # 4个字节 body长度
    # body
    #
    # ip=conn
    while True:
        conn, addr = din.accept()  # 等待接受数据链接
        print('new client')
        clients[addr] = conn;
        print("total connections %s", clients)
    din.close()

t =threading.Thread(target=start_server_async)
t._set_daemon()
t.start()
#关闭连接

print "monitor keyboard start"

def print_pressed_keys(e):
    events = []
    events.append(e)
    keyboard.play(events, speed_factor=3)
    
    keyboard_event = pickle.dumps(e)
    body_bytes = keyboard_event.encode("utf-8")
    head_len = len(body_bytes)
    # 推送给所有已注册的客户端
    delKeys = []
    for ip in clients:
        try:
            clients[ip].send(struct.pack('i', head_len) + body_bytes)
        except Exception as error:
            delKeys.append(ip)

    for delKel in delKeys:
        print ("delete connect %s", delKel)
        clients.pop(ip)
    print  "send end "

#启动监听键盘
keyboard.hook(print_pressed_keys)





